package entities;

import mian.Game;
import utilz.LoadSave;

import java.awt.*;
import java.awt.image.BufferedImage;

import static utilz.Constants.PlayerConstants.*;
import static utilz.HelpMethods.*;

public class Player extends Entity{
    private float yDrawOffset=4* Game.SCALE;
    private float xDrawOffset=21* Game.SCALE;
    private  int[][] lvlData;
    private  float playerSpeed=2.0f;
    private BufferedImage[][]animations;
    private int aniTick, aniIndex,aniSpeed=15;
    private int playerAction= IDLE;
    private boolean left, up, right, down,jump;
    private int playerDir=-1;
    private boolean moving=false;

    private  float airSpeed=0f;
    private float gravity=0.04f*Game.SCALE;
    private float jumpSpeed=-2.25f*Game.SCALE;
    private float fallSpeedAfterCollision =  0.5f*Game.SCALE;
    private boolean inAir=false;
    public void setAttacking(boolean attacking) {
        this.attacking = attacking;
    }
    public void loadLvlData(int [][] lvlData){
        this.lvlData=lvlData;
        if (!IsEntityOnFloor(hitBox,lvlData))
            inAir=true;
    }
    private boolean attacking=false;
    public Player(int x,int y,int width,int height){
        super(x,y,width,height);
        loaAnimnatios();
        initHitBox(x,y,20*Game.SCALE,27*Game.SCALE);
    }
    public void update(){
        updatePos();
        updataAnimationTick();
        setAnimation();
    }
    public void  render(Graphics g){
        g.drawImage(animations[playerAction][aniIndex],(int) (hitBox.x-xDrawOffset),(int)(hitBox.y-yDrawOffset),width,height,null);
//        drawHitBox(g);
    }
    private void loaAnimnatios() {
        BufferedImage img= LoadSave.GetPlayerAtlas(LoadSave.PLAYER_ATLAS);
        animations=new BufferedImage[9][6];
        for (int j = 0; j < animations.length; j++) {
            for (int i = 0; i < animations[j].length; i++) {
                animations[j][i] = img.getSubimage(i * 64, j * 40, 64, 40);
            }
        }}



    private void setAnimation(){
        int startAni=playerAction;
        if (moving){
            playerAction=RUNNING;
        }else
            playerAction=IDLE;
        if (inAir){
            if (airSpeed<0){
                playerAction=JUMP;
            }else
                playerAction=FALLING;
        }
        if (attacking){
            playerAction=ATTACK_1;
        }
        if (startAni !=playerAction){
            resetAniTick();
        }
    }
    private void updataAnimationTick(){
        aniTick++;
        if (aniTick>=aniSpeed){
            aniTick=0;
            aniIndex++;
            if (aniIndex >=GetSpriteAmount(playerAction)){
                aniIndex =0;
                attacking=false;
            }
        }
    }

    public void setLeft(boolean left) {
        this.left = left;
    }

    public void setUp(boolean up) {
        this.up = up;
    }

    public void setRight(boolean right) {
        this.right = right;
    }

    public void setDown(boolean down) {
        this.down = down;
    }
    public void resetAniTick(){
        aniTick=0;
        aniIndex =0;
    }
    public void resetDirBooleans(){
        left=false;
        right=false;
        up=false;
        down=false;
    }
    private  void updatePos() {
        moving=false;
        if (jump)
            jump();
        if (!left && !right&&!inAir)
            return;
         float xSpeed = 0;
        if (left) {
            xSpeed -= playerSpeed;
        }
        if (right ){
            xSpeed += playerSpeed;
        }
        if (!inAir){
            if (!IsEntityOnFloor(hitBox,lvlData))
                inAir=true;
        }
        if (inAir) {
            if (CanMoveHere(hitBox.x,hitBox.y+airSpeed, hitBox.width, hitBox.height, lvlData)) {
                hitBox.y += airSpeed;
                airSpeed += gravity;
                updateXPos(xSpeed);
            } else {
                hitBox.y = GetEntityYposNextTOWall(hitBox, airSpeed);
                if (airSpeed > 0)
                    resetInAir();
                else
                    airSpeed= fallSpeedAfterCollision;
            }
        }else
            updateXPos(xSpeed);

        moving=true;
    }
    private void resetInAir(){
        inAir=false;
        airSpeed=0;
    }
    private void updateXPos(float xSpeed) {
        if (CanMoveHere((hitBox.x+xSpeed),hitBox.y,hitBox.width,hitBox.height,lvlData)){
            hitBox.x+=xSpeed;
        }else {
            hitBox.x=GetEntityXposNextTOWall(hitBox,xSpeed);
        }
    }
    private void jump(){
        if (inAir)
            return;
        inAir=true;
        airSpeed=jumpSpeed;
    }
    public void setJump(boolean jump){
        this.jump=jump;
    }


}